package com.xmwzw.catpu.util;

import android.content.Context;
import android.content.SharedPreferences;
import android.util.Base64;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.StreamCorruptedException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class SPFaceUtils
{
	public static final String FILE_NAME = "catPu";


	public static <T>  void put(Context context, String key, T object) {
		if(context == null || object == null){
			return;
		}
		SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
				Context.MODE_PRIVATE);
		SharedPreferences.Editor editor = sp.edit();

		if (object instanceof String) {
			editor.putString(key, (String) object);
		} else if (object instanceof Integer) {
			editor.putInt(key, (Integer) object);
		} else if (object instanceof Boolean) {
			editor.putBoolean(key, (Boolean) object);
		} else if (object instanceof Float) {
			editor.putFloat(key, (Float) object);
		} else if (object instanceof Long) {
			editor.putLong(key, (Long) object);
		} else {
			saveObjectSP(editor,key,object);
			return;
		}
		SharedPreferencesCompat.apply(editor);
	}

	private static void saveObjectSP(SharedPreferences.Editor editor, String key, Object object)
	{
		//创建字节输出流
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		//创建字节对象输出流
		ObjectOutputStream out = null;
		try {
			//然后通过将字对象进行64转码，写入key值为key的sp中
			out = new ObjectOutputStream(baos);
			out.writeObject(object);
			String objectVal = new String(Base64.encode(baos.toByteArray(), Base64.DEFAULT));
			//用putString的方法保存数据
			editor.putString(key, objectVal);
			SharedPreferencesCompat.apply(editor);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				baos.close();
				if (out != null) {
					out.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}


	}


	public static <T> T get(Context context, String key, T defaultObject) {
		if(context == null){return null;}
		SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
				Context.MODE_PRIVATE);
		Object o = null;
		if (defaultObject instanceof String) {
			 o = sp.getString(key, (String) defaultObject);
		} else if (defaultObject instanceof Integer) {
			o = sp.getInt(key, (Integer) defaultObject);
		} else if (defaultObject instanceof Boolean) {
			o = sp.getBoolean(key, (Boolean) defaultObject);
		} else if (defaultObject instanceof Float) {
			o =sp.getFloat(key, (Float) defaultObject);
		} else if (defaultObject instanceof Long) {
			o = sp.getLong(key, (Long) defaultObject);
		}else {
			o = getObjectSP(sp,key,defaultObject);
		}
		T t = (T)o;
		return t;
	}

	private static Object getObjectSP(SharedPreferences sp, String key, Object object)
	{
		if(sp == null){ return object; }
		if (sp.contains(key)) {
			ByteArrayInputStream bais = null;
			ObjectInputStream ois = null;
			try {
				String objectVal = sp.getString(key, null);
				byte[] buffer = Base64.decode(objectVal, Base64.DEFAULT);
				//一样通过读取字节流，创建字节流输入流，写入对象并作强制转换
				bais = new ByteArrayInputStream(buffer);
				ois = new ObjectInputStream(bais);
				return 	ois.readObject();
			} catch (StreamCorruptedException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			} finally {
				try {
					if (bais != null) {
						bais.close();
					}
					if (ois != null) {
						ois.close();
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return object;


	}


	public static void clear(Context context) {
		SharedPreferences sp = context.getApplicationContext().getSharedPreferences(FILE_NAME,
				Context.MODE_PRIVATE);
		SharedPreferences.Editor editor = sp.edit();
		editor.clear();
		SharedPreferencesCompat.apply(editor);
	}


	public static void clearOnes(Context context, String... keys) {
		SharedPreferences sp = context.getApplicationContext().getSharedPreferences(FILE_NAME,
				Context.MODE_PRIVATE);
		for (String key :keys){
			if(sp.contains(key)){
				SharedPreferences.Editor editor = sp.edit();
				editor.remove(key);
				SharedPreferencesCompat.apply(editor);
			}
		}
	}




	/**
	 * 查询某个KEY是否存在
	 */
	public static boolean contains(Context context, String key) {
		SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
				Context.MODE_PRIVATE);
		return sp.contains(key);
	}
	private static class SharedPreferencesCompat {
		private static final Method sApplyMethod = findApplyMethod();

		/**
		 * 反射查找apply的方法
		 *
		 * @return
		 */
		@SuppressWarnings({"unchecked", "rawtypes"})
		private static Method findApplyMethod() {
			try {
				Class clz = SharedPreferences.Editor.class;
				return clz.getMethod("apply");
			} catch (NoSuchMethodException e) {
			}

			return null;
		}

		/**
		 * 如果找到则使用apply执行，否则使用commit
		 *
		 * @param editor
		 */
		public static void apply(SharedPreferences.Editor editor) {
			try {
				if (sApplyMethod != null) {
					sApplyMethod.invoke(editor);
					return;
				}
			} catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) {
				e.printStackTrace();
			}
			editor.commit();
		}
	}


}
